<?php
/***
 * Candy框架 page类
 * 
 * $Author: 刘森 (fingerboy@qq.com) $
 * $Date: 2019-12-08 13:49:18 $   
 */
 
declare(strict_types=1);
namespace Candy\Extend;

defined('CANDY') OR die('You Are A Bad Guy. o_O???');

class Page {
	public $config;	//样式配置文件
	private $style;	//css文件
	public $url;	//连接网址
	public $page;	//当前页
	public $total;	//总数
	public $totalPages; //分页总数
	public $num;	//每个页面显示的post数目
	public $perCircle;	 //list允许放页码数量,如:1.2.3.4就这4个数字,则$perCircle为4
	public $ext; //分页程序的扩展功能开关,默认关闭
	public $center;	//list中的坐标. 如:7,8,九,10,11这里的九为当前页,在list中排第三位,则$center为3
	public $firstPage;	//第一页
	public $prePage;	//上一页
	public $nextPage; //下一页
	public $lastPage;	//最后一页
	public $note;	//分页附属说明
	public $isAjax;	//是否为ajax分页模式
	public $ajaxActionName; //ajax分页的动作名称
	public $styleFile; //分页css名
	public $hiddenStatus; //分页隐藏开关
	
	
	/**
	 * 构造函数
	 * 
	 * @access public
	 * @return boolean
	 */
	public function __construct()
	{
		$this->ext 			 = true;
		$this->center 		 = 4;
		$this->num 			 = 7;
		$this->perCircle	 = 7;
		$this->isAjax		 = false;
		$this->hiddenStatus = false;
		return true;
	}
	
	/**
	 * 显示样式配置
	 *
	 * @param array $config
	 * $div HTMLdiv盒结构 (<div id="pages">{content}</div>)
	 * $total 显示统计数量 (<a>{content}</a>)
	 * $nowpage 当前页 (<span>{content}</span>)
	 * $page 普通页 (<a href="{url}">{content}</a>)
	 * $pre 上一页 (<a href="{url}">{content}</a>)
	 * $next 下一页 (<a href="{url}">{content}</a>)
	 */
	public function loadConfig(array $config = []): void
	{
	    if (empty($config)) {
	        $config = array(
				'div'     => '<div id="pages">{content}</div>',
				'total'   => '<a>{content}</a>',
				'nowpage' => '<span>{content}</span> ',
				'page'    => '<a href="{url}">{content}</a>',
				'pre'     => '<a href="{url}">{content}</a>',
				'next'    => '<a href="{url}">{content}</a>',
				'note'    => '<a>{content}</a>'
	        );
	    }
	    $this->firstPage	= $this->firstPage ? $this->firstPage : '首页';
		$this->prePage 		= $this->prePage ? $this->prePage : '上一页';
		$this->nextPage		= $this->nextPage ? $this->nextPage : '下一页';
		$this->lastPage		= $this->lastPage ? $this->lastPage : '末页';
		$this->note			= empty($config['note']) ? '共{total_num}条. {total_page}页 {num}条/页' : $config['note'];
	    $this->config		= $config;
	}
	
	private function pregContent($content, $url='', $config): string
	{
	    return str_replace('{content}', $content, str_replace('{url}', $url, $config));
	}
	
	/**
	 * 获取总页数
	 * 
	 * @return integer
	 */
	private function getTotalPage(): int
	{
		if (!$this->total || !$this->num) return false;
		return ceil($this->total / $this->num);
	}
	
	/**
	 * 获取当前页数
	 * 
	 * @return integer
	 */
	private function getPageNum(): int
	{
		$page = (!$this->page) ? 1 : (int)$this->page;
		//当URL中?page=5的page参数大于总页数时
		return ($page > $this->totalPages) ? (int)$this->totalPages : $page;
	}
	
	/**
	 * 返回$this->num=$num.
	 * 
	 * @param integer $num
	 * @return $this
	 */
	public function num($num = null): Page
	{	
		//参数分析
		if (is_null($num)) $num = 10;
		$this->num = (int)$num;
		return $this;
	}

	/**
	 * 返回$this->total=$total_post.
	 * 
	 * @param integer $total_post
	 * @return $this
	 */
	public function total($total_post = null): Page
	{
		$this->total = (!is_null($total_post)) ? (int)$total_post : 0;
		return $this;
	}
	
	/**
	 * 开启分页的隐藏功能
	 * 
	 * @access public
	 * @param boolean $item	隐藏开关 , 默认为true.
	 * @return $this
	 */
	public function hide(bool $item = true): Page
	{
		if ($item === true) $this->hiddenStatus = true;
		return $this;
	}
	
	protected function setUrl(string $url,int $page): string
	{
	    return str_replace('{page}', $page, $url);
	}

	/**
	 * 返回$this->url=$url.
	 * 
	 * @param string $url
	 * @return $this
	 */
	public function url($url = null): Page
	{
		//当url为空时,自动获取url参数. 注:默认当前页的参数为page
		if (is_null($url)) {
			//当网址没有参数时
			$url = (!$_SERVER['QUERY_STRING']) ? $_SERVER['REQUEST_URI'] . ((substr($_SERVER['REQUEST_URI'], -1) == '?') ? 'page={page}' : '?page={page}') : '';
			//当网址有参数时,且有分页参数(page)时
			if (!$url && (stristr($_SERVER['QUERY_STRING'], 'page='))) {	
				$url = str_ireplace('page=' . $this->page, '', $_SERVER['REQUEST_URI']);	
				$end_str = substr($url, -1);			
				if ($end_str == '?' || $end_str == '&') {
					$url .= 'page={page}';
				} else {
					$url .= '&page={page}';
				}
			}
			//当网址中未发现含有分页参数(page)时
			if (!$url) $url = $_SERVER['REQUEST_URI'] . '&page={page}';
		}
		//自动获取都没获取到url...额..没有办法啦, 趁早返回false
		if (!$url) return false;
		$this->url = empty($this->config['before']) ? trim($url) : $this->config['before'] . trim($url);
		$this->url = empty($this->config['after']) ? trim($this->url) : trim($this->url) . $this->config['after'];
		return $this;
	}

	/**
	 * 返回$this->page=$page.
	 * 
	 * @param integer $page
	 * @return $this
	 */
	public function page($page = null): Page
	{
		//当参数为空时.自动获取GET['page']
		if (is_null($page)) {
			$page = C('page') ?: (I('get.page') ?: 1);
		}
		if(!$page) return false;
		$this->page = $page;
		return $this;
	}

	/**
	 * 返回$this->ext=$ext.
	 * 
	 * @param boolean $ext
	 * @return $this
	 */
	public function ext(bool $ext = true): Page
	{
		//将$ext转化为小写字母.
		$this->ext = ($ext) ? true : false;
		return $this;
	}

	/**
	 * 返回$this->center=$num.
	 * 
	 * @param integer $num
	 * @return $this
	 */
	public function center($num): Page
	{
		if (!$num) return false;
		$this->center = (int)$num;
		return $this;
	}

	/**
	 * 返回$this->perCircle=$num.
	 * 
	 * @param integer $num
	 * @return $this
	 */
	public function circle($num): Page
	{
		if (!$num) return false;
		$this->perCircle = (int)$num;
		return $this;
	}
	
	/**
	 * 处理第一页,上一页
	 * 
	 * @return string
	 */
	private function getFirstPage(): string
	{
		if ($this->page == 1 || $this->totalPages <= 1) return false;
		$string = $this->pregContent($this->firstPage, $this->setUrl($this->url, 1), $this->config['first']) . $this->pregContent($this->prePage, $this->setUrl($this->url, $this->page - 1), $this->config['pre']);
		return $string;
	}
	
	/**
	 * 处理下一页,最后一页
	 * 
	 * @return string
	 */
	private function getLastPage(): string
	{
		if ($this->page == $this->totalPages || $this->totalPages <= 1) return false;
		$string = $this->pregContent($this->nextPage, $this->setUrl($this->url, $this->page + 1), $this->config['next']) . $this->pregContent($this->lastPage, $this->setUrl($this->url, $this->totalPages), $this->config['last']);
		return $string;
	}
	
	/**
	 * 处理注释内容
	 * 
	 * @return string
	 */
	private function getNote()
	{
		if (!$this->ext || !$this->note) return false;
		return str_replace(['{total_num}', '{total_page}', '{num}','{page}','{url}'], [$this->total, $this->totalPages, $this->num, $this->page, $this->setUrl($this->url, $this->page)], $this->pregContent($note, $this->setUrl($this->url, $this->page), $this->note));
	}
	
	/**
	 * 处理list内容
	 * 
	 * @return string
	 */
	private function getList()
	{
		if (empty($this->totalPages) || empty($this->page)) return false;
		if ($this->totalPages > $this->perCircle) {				
			if ($this->page + $this->perCircle >= $this->totalPages + $this->center) {					
				$list_start  = $this->totalPages - $this->perCircle + 1;
				$list_end  	= $this->totalPages;
			} else {		 			
				$list_start  = ($this->page>$this->center) ? $this->page - $this->center + 1 : 1;
				$list_end 	 = ($this->page>$this->center) ? $this->page + $this->perCircle-$this->center : $this->perCircle;
			}				
		} else {				
			$list_start 	 = 1;
			$list_end 	     = $this->totalPages;
		}
		$pagelist_queue      = '';
		for ($i=$list_start; $i<=$list_end; $i++) {
			$pagelist_queue .= ($this->page == $i) ? $this->pregContent($i, null, $this->config['nowpage']) : $this->pregContent($i, $this->setUrl($this->url, $i), $this->config['page']);
		}
		return $pagelist_queue;
	}
	
	/**
	 * 输出处理完毕的HTML
	 * 
	 * @return string
	 */
	public function output(): string
	{
		//支持长的url.
		empty($this->url) && $this->url();
		$this->url = trim(str_replace(array("\n","\r"), '', $this->url));
		//获取总页数.
		$this->totalPages = $this->getTotalPage();
		//获取当前页.
		$this->page = $this->getPageNum();
		return ($this->total <= $this->num) ? '' : $this->pregContent($this->getNote() . $this->getFirstPage() . $this->getList() . $this->getLastPage() , '', $this->config['div']);
	}
	
	/**
	 * 析构函数
	 * 
	 * @access public
	 * @return void
	 */
	public function __destruct() {
		
	}
}
